﻿using ServiceCore.DbContext;
using ServiceCore.Entity.Arg;
using ServiceCore.Entity.Const.Record;
using ServiceCore.Entity.Model;
using ServiceCore.Utility.Extension;

namespace ServiceCore.Service
{
    /// <summary>
    /// 标签类型
    /// </summary>
    public partial class TextParseService : SqlsugarServices<RecordInfo>
    {
        #region 标签类型解析-各
        public void Text_Parse_TagType_Each_Verify(ArgTextParse arg)
        {
            arg.lstParse = new List<TextParseDto>();
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Datas.Any() == false)
                return;
            arg.lstParse = arg.Datas.Where(x => x.ParsemChildMode == ParsemChildMode.ParsemChildMode_TagType_Each && x.IsParseSuccess == false).ToList();
            if (arg.lstParse.Any() == false)
                return;

            decimal? value = 0;
            string tagStr = string.Empty;
            string gongStr = string.Empty;
            var idx = -1;
            foreach (var item in arg.lstParse)
            {
                value = NumberExtractor.ExtractDecimalAfterGong(item.SourceProcess, '各');
                idx = item.SourceProcess.IndexOf("各");
                if (idx > -1 && idx != item.SourceProcess.LastIndexOf("各"))
                    continue;//多个各不处理

                if (value.HasValue == false)
                {
                    item.Result = ParsemResult.ParsemResult_Fail;
                    item.ResultTip = "获取金额失败";
                    continue;
                }
                tagStr = item.SourceProcess.Split('各')[0];
                if (string.IsNullOrWhiteSpace(tagStr))
                {
                    item.SourceProcess = item.SourceProcess.Replace("各", ""); //各羊10元【失败原因：获取金额失败】
                    item.SourceProcess = item.SourceProcess.FirstNumberBeforeAddTxt("各");

                    tagStr = item.SourceProcess.Split('各')[0];
                    if (string.IsNullOrWhiteSpace(tagStr))
                    {
                        item.Result = ParsemResult.ParsemResult_Fail;
                        item.ResultTip = "获取标签失败";
                        continue;
                    }
                }
                gongStr = string.Empty;
                if (item.SourceProcess.Contains("共"))
                {
                    gongStr = item.SourceProcess.Split('共')[1];
                }

                tagStr = tagStr.GetTxtReplaceNumeric();
                item.SourceProcess = tagStr + "各" + value;
                if (string.IsNullOrEmpty(gongStr) == false)
                    item.SourceProcess += "共" + gongStr;
            }
        }

        public void Text_Parse_TagType_Each(ArgTextParse arg)
        {
            Text_Parse_TagType_Each_Verify(arg);
            if (arg.lstParse.Any() == false)
                return;

            arg.lstParse.ForEach(x =>
            {
                if (x.SourceProcess.GetCharCount('各') == 1)
                {
                    x = Text_Parse_TagType_Each_Single(x, arg.lstTag);
                }
                else
                {
                    x = Text_Parse_TagType_Each_Multiple(x, arg.lstTag);
                }

                x.lstTag.ForEach(x => x.CreateTime = arg.CurTime);
            });            
        }

        public TextParseDto Text_Parse_TagType_Each_Single(TextParseDto item, List<TagInfo> lstTag)
        {
            var tags = new List<TagInfo>();
            var value = NumberExtractor.ExtractDecimalAfterGong(item.SourceProcess, '各');
            if (value.HasValue == false)
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "获取金额失败";
                return item;
            }
            var tagStr = item.SourceProcess.Split('各')[0];
            if (string.IsNullOrWhiteSpace(tagStr))
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "获取标签类型失败";
                return item;
            }
            tagStr = tagStr.Replace(" ", "");
            foreach (char tagTypeName in tagStr)
            {
                tags = lstTag.Where(x => x.TagTypeName == tagTypeName.ToString()).ToList();
                if (tags.Any() == false)
                    continue;

                //设置值
                tags.ForEach(x => item.lstTag.Add(new TagInfo() { Id = x.Id, TagTypeId = x.TagTypeId, TagTypeName = x.TagTypeName, Name = x.Name, DataValue = value.Value}));
            }

            //结果校验
            if (item.lstTag.Any() == false)
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "无对应标签类型";
                return item;
            }
            if (item.Total.HasValue && item.lstTag.Sum(x => x.DataValue) != item.Total)
            {
                item.Result = ParsemResult.ParsemResult_Warn;
                item.ResultTip = "不等于合计";
                return item;
            }
            item.Result = ParsemResult.ParsemResult_Success;
            item.IsParseSuccess = true;
            return item;
        }

        public TextParseDto Text_Parse_TagType_Each_Multiple(TextParseDto item, List<TagInfo> lstTag)
        {
            var tagDatas = item.SourceProcess.Split(';');
            var oldSourceProcess = item.SourceProcess;

            foreach (var tagData in tagDatas)
            {
                item.SourceProcess = tagData;
                Text_Parse_TagType_Each_Single(item, lstTag);
            }

            item.SourceProcess = oldSourceProcess;
            if (item.lstTag.Any())
            {
                if (item.Total.HasValue && item.lstTag.Sum(x => x.DataValue) != item.Total)
                {
                    item.Result = ParsemResult.ParsemResult_Warn;
                    item.ResultTip = "不等于合计";
                }
                else
                    item.Result = ParsemResult.ParsemResult_Success;
            }

            return item;
        }
        #endregion

        #region 标签类型解析-通用
        public void Text_Parse_TagType_General_Verify(ArgTextParse arg)
        {
            arg.lstParse = new List<TextParseDto>();
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Datas.Any() == false)
                return;
            arg.lstParse = arg.Datas.Where(x => x.ParsemChildMode == ParsemChildMode.ParsemChildMode_TagType_General && x.IsParseSuccess == false).ToList();
            if (arg.lstParse.Any() == false)
                return;

            var commaCnt = 0;
            List<string>? nums;
            long? value = 0;
            var idx = -1;
            foreach (var item in arg.lstParse)
            {
                item.SourceProcess = item.SourceProcess.Replace("  ", " ");
                item.SourceProcess = item.SourceProcess.Replace(" ", ",");
                item.SourceProcess = item.SourceProcess.Replace(" ", ",");
                item.SourceProcess = item.SourceProcess.Replace(".", ",");
                item.SourceProcess = item.SourceProcess.Replace("。", ",");
                item.SourceProcess = item.SourceProcess.Replace("/", ",");
                item.SourceProcess = item.SourceProcess.Replace("-", ",");
                item.SourceProcess = item.SourceProcess.Replace("+", ",");

                if (item.SourceProcess.Contains("号"))
                    item.SourceProcess = item.SourceProcess.Replace("号", "打"); //24号5【失败原因：获取金额失败】
                else if (item.SourceProcess.Contains(","))
                {
                    nums = new List<string>();
                    commaCnt = item.SourceProcess.GetCharCount(',');
                    if (commaCnt == 1)
                    {
                        int lastCommaIndex = item.SourceProcess.LastIndexOf(',');
                        if (lastCommaIndex > 0)
                        {
                            if (item.SourceProcess.Substring(lastCommaIndex - 1, 1).IsHaveNumeric())
                            {
                                //鼠40,蛇50
                                nums = item.SourceProcess.Split(',').ToList();
                                nums = nums.Where(x => string.IsNullOrWhiteSpace(x) == false).ToList();
                                item.SourceProcess = string.Empty;
                                foreach (var numStr in nums)
                                {
                                    value = numStr.GetTxtNumeric();
                                    if (value.HasValue == false)
                                        continue;

                                    item.SourceProcess += numStr.Replace(value.ToString(), "") + "打" + value + ";";
                                }
                            }
                            else
                            {
                                //鼠,40
                                item.SourceProcess = item.SourceProcess.ReplaceLastComma("打");
                            }
                        }
                    }
                    else
                    {
                        
                        idx = item.SourceProcess.IndexOf("打");
                        if (idx > 0 && item.SourceProcess.LastIndexOf("打") == idx)
                        {
                            //兔蛇牛猴 四连肖打十块 共90
                            var ss = item.SourceProcess.Split('打');
                            if (ss.Length >= 2)
                            {
                                item.SourceProcess = string.Empty;
                                var tempTags = new List<string>();
                                foreach (char tagTypeName in ss[0])
                                {
                                    if (arg.lstTagTypeName.Any(x => x == tagTypeName.ToString()))
                                        item.SourceProcess += tagTypeName.ToString();
                                }
                                var gong = "";
                                if (ss[1].Contains("共"))
                                {
                                    gong = ss[1].Split('共')[1];
                                    ss[1] = ss[1].Split('共')[0];
                                }
                                item.SourceProcess = item.SourceProcess + "打" + ss[1].GetTxtNumeric();
                                if (string.IsNullOrEmpty(gong) == false)
                                    item.SourceProcess += "共" + gong;
                            }
                        }
                        else
                        {
                            //鼠40,蛇50,龙30
                            nums = item.SourceProcess.Split(',').ToList();
                            nums = nums.Where(x => string.IsNullOrWhiteSpace(x) == false).ToList();

                            //有生效并且有数字
                            item.SourceProcess = string.Empty;
                            foreach (var numStr in nums)
                            {
                                idx = -1;
                                foreach (var c in numStr)
                                {
                                    idx = arg.lstTagTypeName.IndexOf(c.ToString());
                                    if (idx > -1)
                                        break;
                                }
                                if (idx == -1)
                                    continue;
                                if (numStr.Replace(arg.lstTagTypeName[idx], "").IsHaveNumeric())
                                {
                                    value = numStr.GetTxtNumeric();
                                    if (value.HasValue == false)
                                        continue;

                                    item.SourceProcess += numStr.Replace(value.ToString(), "") + "打" + value + ";";
                                } 
                            }
                        }
                    }
                }
                else if (item.SourceProcess.IsHaveNumeric())
                {
                    item.SourceProcess = item.SourceProcess.FirstNumberBeforeAddTxt("打"); //猴100总计145【失败原因：获取金额失败】
                }
            }
        }

        public void Text_Parse_TagType_General(ArgTextParse arg)
        {
            Text_Parse_TagType_General_Verify(arg);
            if (arg.lstParse.Any() == false)
                return;

            arg.lstParse.ForEach(x =>
            {
                if (x.SourceProcess.GetCharCount('打') == 1)
                {
                    x = Text_Parse_TagType_General_Single(x, arg.lstTag);
                }
                else
                {
                    x = Text_Parse_TagType_General_Multiple(x, arg.lstTag);
                }

                x.lstTag.ForEach(x => x.CreateTime = arg.CurTime);
            });            
        }

        /// <summary>
        /// 标签类型解析-通用-单个
        /// </summary>
        /// <param name="arg"></param>
        public TextParseDto Text_Parse_TagType_General_Single(TextParseDto item, List<TagInfo> lstTag)
        {
            var value = NumberExtractor.ExtractDecimalAfterGong(item.SourceProcess, '打');
            if (value.HasValue == false)
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "获取金额失败";
                return item;
            }

            var tagStr = item.SourceProcess.Split('打')[0];
            if (string.IsNullOrWhiteSpace(tagStr))
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "获取标签类型失败";
                return item;
            }
            tagStr = tagStr.TrimStart().TrimEnd();

            List<TagInfo> tags = new List<TagInfo>(), tempTags = new List<TagInfo>();
            var tag = new TagInfo();
            if (tagStr.Contains(',') == false)
            {
                //单个
                foreach (char tagTypeName in tagStr)
                {
                    tempTags = lstTag.Where(x => x.TagTypeName == tagTypeName.ToString()).ToList();
                    if (tempTags.Any() == false)
                        continue;

                    tempTags.ForEach(x => tags.Add(new TagInfo() { Id = x.Id, TagTypeId = x.TagTypeId, TagTypeName = x.TagTypeName, Name = x.Name, DataValue = value.Value }));
                }
            }
            else
            {
                //多个
                var lstTagName = tagStr.Split(",").ToList();
                foreach (var _tagTypeName in tempTags)
                {
                    tempTags = lstTag.Where(x => x.TagTypeName == _tagTypeName.ToString()).ToList();
                    if (tempTags.Any() == false)
                        continue;

                    //设置值
                    tempTags.ForEach(x => tags.Add(new TagInfo() { Id = x.Id, TagTypeId = x.TagTypeId, TagTypeName = x.TagTypeName, Name = x.Name, DataValue = value.Value }));
                }
            }

            if (tags.Any() == false)
            {
                item.Result = ParsemResult.ParsemResult_Fail;
                item.ResultTip = "无对应标签";
                return item;
            }
            if (item.Total.HasValue && item.lstTag.Sum(x => x.DataValue) != item.Total)
            {
                item.Result = ParsemResult.ParsemResult_Warn;
                item.ResultTip = "不等于合计";
            }
            else
                item.Result = ParsemResult.ParsemResult_Success;

            item.lstTag.AddRange(tags);
            item.IsParseSuccess = true;
            return item;
        }

        /// <summary>
        /// 标签类型解析-通用-多个
        /// </summary>
        /// <param name="arg"></param>
        public TextParseDto Text_Parse_TagType_General_Multiple(TextParseDto item, List<TagInfo> lstTag)
        {
            var tagDatas = item.SourceProcess.Split(';');
            var oldSourceProcess = item.SourceProcess;

            foreach (var tagData in tagDatas)
            {
                item.SourceProcess = tagData;
                Text_Parse_TagType_General_Single(item, lstTag);
            }

            item.SourceProcess = oldSourceProcess;
            if (item.lstTag.Any())
            {
                if (item.Total.HasValue && item.lstTag.Sum(x => x.DataValue) != item.Total)
                {
                    item.Result = ParsemResult.ParsemResult_Warn;
                    item.ResultTip = "不等于合计";
                }
                else
                    item.Result = ParsemResult.ParsemResult_Success;
            }

            return item;
        }
        #endregion

        #region 标签类型解析-包
        public void Text_Parse_TagType_Pack_Verify(ArgTextParse arg)
        {
            arg.lstParse = new List<TextParseDto>();
            if (string.IsNullOrEmpty(arg.ErrorMsg) == false)
                return;
            if (arg.Datas.Any() == false)
                return;

            var lstPack = new List<TextParseDto>();
            for (int i = arg.Datas.Count - 1; i >= 0; i--)
            {
                if (arg.Datas[i].ParsemChildMode == ParsemChildMode.ParsemChildMode_TagType_Pack && arg.Datas[i].IsParseSuccess == false)
                {
                    lstPack.Add(arg.Datas[i]);
                    arg.Datas.RemoveAt(i);
                }
            }
            if (lstPack.Any() == false)
                return;
            arg.lstParse = new List<TextParseDto>();

            var lstPackAdd = new List<TextParseDto>();
            var lstSource = new List<string>();
            var lstContents = new List<string>();
            var lstPackStr = new List<string>();
            var commaCnt = 0;
            decimal value = 0;
            long? allValue;
            var tagTypeNme = string.Empty;
            long? tagTypeValue = 0;
            var idx = -1;
            foreach (var item in lstPack)
            {
                if (item.Result == ParsemResult.ParsemResult_Fail)
                    continue;

                item.SourceProcess = item.SourceProcess.Replace("  ", " ");
                item.SourceProcess = item.SourceProcess.Replace(" ", ",");
                item.SourceProcess = item.SourceProcess.Replace(" ", ",");
                item.SourceProcess = item.SourceProcess.Replace(".", ",");
                item.SourceProcess = item.SourceProcess.Replace("。", ",");
                item.SourceProcess = item.SourceProcess.Replace("/", ",");
                item.SourceProcess = item.SourceProcess.Replace("-", ",");
                item.SourceProcess = item.SourceProcess.Replace("+", ",");

                lstSource = item.SourceProcess.Split(',').ToList();
                lstSource.ForEach(x => x = x.TrimStart().TrimEnd());
                if (lstSource.Any() == false)
                    continue;

                //鸡，兔，狗，三肖，1百，澳
                idx = item.SourceProcess.IndexOf("包");
                if (idx > -1 && idx == item.SourceProcess.LastIndexOf("包") && lstSource.Count >= 2)
                {                    
                    allValue = item.SourceProcess.Split('包')[1].GetTxtNumeric();
                    if (allValue.HasValue)
                    {                        
                        lstSource = lstSource.Where(x => x.Any(n => arg.lstTagTypeName.Contains(n.ToString()))).ToList();
                        if (lstSource.Any())
                        {
                            for (int i = 0; i < lstSource.Count; i++)
                            {
                                lstSource[i] = lstSource[i] + "包" + allValue;
                            }
                        }                        
                    }
                }

                lstSource = lstSource.Where(x => string.IsNullOrWhiteSpace(x) == false && x.Contains("包")).ToList();
                if (lstSource.Any() == false)
                    continue;
                lstPackStr = new List<string>();
                foreach (var pack in lstSource)
                {
                    //标签类型
                    tagTypeNme = pack.FindFirstMatchIndexOf(arg.lstTagTypeName);//马包10,羊包10,共20
                    if (string.IsNullOrEmpty(tagTypeNme))
                        continue;
                    //标签合计值
                    lstContents = pack.Split('共').ToList();
                    if (lstContents.Count > 1)
                    { 
                        if(lstContents[0].IsHaveNumeric())
                            tagTypeValue = lstContents[0].GetTxtNumeric();
                        else
                            tagTypeValue = lstContents[1].GetTxtNumeric();//10包马,10包羊,共20
                    }
                    else
                        tagTypeValue = pack.GetTxtNumeric();
                    if (tagTypeValue.HasValue == false)
                        continue;

                    //标签值
                    commaCnt = arg.lstTag.Where(x => x.TagTypeName == tagTypeNme).Count();
                    if (commaCnt == 0)
                        continue;
                    value = Math.Round((decimal)tagTypeValue / commaCnt, 2, MidpointRounding.AwayFromZero);
                    if (value <= 0)
                        continue;

                    lstPackStr.Add($"{tagTypeNme}各{value.ToString("0.00")}");
                }
                if (lstPackStr.Any() == false)
                    continue;
                
                arg.lstParse.Add(new TextParseDto()
                {
                    ParsemMode = item.ParsemMode,
                    ParsemChildMode = ParsemChildMode.ParsemChildMode_TagType_Pack,
                    ServiceType = item.ServiceType,
                    Source = item.Source,
                    SourceProcess = string.Join(";", lstPackStr)
                });
            }
        }

        public void Text_Parse_TagType_Pack(ArgTextParse arg)
        {
            Text_Parse_TagType_Pack_Verify(arg);
            if (arg.lstParse.Any() == false)
                return;

            arg.lstParse.ForEach(x =>
            {
                if (x.SourceProcess.GetCharCount('各') == 1)
                {
                    x = Text_Parse_TagType_Each_Single(x, arg.lstTag);
                }
                else
                {
                    x = Text_Parse_TagType_Each_Multiple(x, arg.lstTag);
                }

                x.lstTag.ForEach(x => x.CreateTime = arg.CurTime);
            }); 
            arg.Datas.AddRange(arg.lstParse);
        }
        #endregion

        #region 拆行
        public void Text_Parse_TagType_ChangLine(ArgTextParse arg) 
        {
            /*
                澳,06.15.26.37.47.48各5,狗20,共50
                12-45各五块，7-24各十块，猪各号五块合计50
                7-17-13-5各五块，猪各号五块，合计40香港的
                马/40，24/10，澳大特，总计50
             */
            int idx = -1;
            var newDatas = new List<TextParseDto>();
            var selectTagTypeNames = new List<string>();
            string firstPart = string.Empty, secondPart = string.Empty;
            foreach (var item in arg.Datas.Where(x => (
                    x.ParsemChildMode == ParsemChildMode.ParsemChildMode_TagType_General
                    || x.ParsemChildMode == ParsemChildMode.ParsemChildMode_TagType_Each)
                        && x.IsParseSuccess == false))
            {
                //包含：各和共
                item.SourceProcess = string.IsNullOrEmpty(item.SourceProcess) ? item.Source : item.SourceProcess;
                if (item.SourceProcess.Contains("共") == false)
                    continue;

                //是否包含生肖
                selectTagTypeNames = new List<string>();
                foreach (char c in item.SourceProcess)
                {
                    if (arg.lstTagTypeName.IndexOf(c.ToString()) > -1)
                        selectTagTypeNames.Add(c.ToString());
                }
                if (selectTagTypeNames.Count != 1)
                    continue;
                               
                idx = item.SourceProcess.IndexOf(selectTagTypeNames[0]);
                firstPart = item.SourceProcess.Substring(0, idx);
                secondPart = item.SourceProcess.Substring(idx);
                secondPart = secondPart.Split('共')[0];
                if (idx == 0)
                {
                    if (item.SourceProcess.Contains(',') == false)
                        continue;

                    //马/40，24/10，澳大特，总计50
                    idx = item.SourceProcess.IndexOf(",");
                    firstPart = item.SourceProcess.Substring(0, idx);
                    secondPart = item.SourceProcess.Substring(idx);
                    secondPart = secondPart.Split('共')[0];

                    //数字行
                    newDatas.Add(new TextParseDto()
                    {
                        Source = secondPart,
                        SourceProcess = secondPart,
                        ServiceType = item.ServiceType,
                        ParsemMode = ParsemMode.ParsemMode_Tag,
                        ParsemChildMode = firstPart.Contains("各") ? ParsemChildMode.ParsemChildMode_Tag_Each : ParsemChildMode.ParsemChildMode_Tag_General,
                        SiteId = item.SiteId
                    });

                    //生肖行
                    if (firstPart.Contains("各") == false && firstPart.Contains("包") == false)
                        firstPart = firstPart.Replace(selectTagTypeNames[0], $"{selectTagTypeNames[0]}包");
                    newDatas.Add(new TextParseDto()
                    {
                        Source = firstPart,
                        SourceProcess = firstPart,
                        ServiceType = item.ServiceType,
                        ParsemMode = ParsemMode.ParsemMode_TagType,
                        ParsemChildMode = firstPart.Contains("各") ? ParsemChildMode.ParsemChildMode_TagType_Each : ParsemChildMode.ParsemChildMode_TagType_Pack,
                        SiteId = item.SiteId
                    });
                    continue;
                }

                //生肖行
                if (secondPart.Contains("各") == false && secondPart.Contains("包") == false)
                    secondPart = secondPart.Replace(selectTagTypeNames[0], $"{selectTagTypeNames[0]}包");
                newDatas.Add(new TextParseDto()
                {
                    Source = secondPart,
                    SourceProcess = secondPart,
                    ServiceType = item.ServiceType,
                    ParsemMode = ParsemMode.ParsemMode_TagType,
                    ParsemChildMode = secondPart.Contains("各") ? ParsemChildMode.ParsemChildMode_TagType_Each : ParsemChildMode.ParsemChildMode_TagType_Pack,
                    SiteId = item.SiteId
                });
                //数字行
                idx = firstPart.IndexOf("各");
                if (idx > -1 && idx != firstPart.LastIndexOf("各"))
                { 
                    //多个各

                }
                newDatas.Add(new TextParseDto()
                {
                    Source = firstPart,
                    SourceProcess = firstPart,
                    ServiceType = item.ServiceType,
                    ParsemMode = ParsemMode.ParsemMode_Tag,
                    ParsemChildMode = ParsemChildMode.ParsemChildMode_Tag_Each,
                    SiteId = item.SiteId
                });                
            }
            if (newDatas.Any() == false)
                return;

            ArgTextParse argNew = new ArgTextParse() { Datas = newDatas, lstTagType = arg.lstTagType, lstTagTypeName = arg.lstTagTypeName, lstTag = arg.lstTag };
            Text_Parse_TagType_Pack(argNew); //标签类型-包含包
            Text_Parse_TagType_Each(argNew); //标签类型-包含各
            Text_Parse_Tag_Each(argNew); //标签-包含各
            Text_Parse_Tag_General(argNew); //标签-通用
            arg.Datas.AddRange(argNew.Datas);
            arg.lstTag.AddRange(argNew.lstTag);
        }
        #endregion
    }
}
